/*
 * Created on Jun 12, 2005
 */
package clustering.implementations;

import org.w3c.dom.*;
import java.util.*;
import clustering.framework.*;

/**
 * @author Tudor.Ionescu@supelec.fr

FlatTreeComparer

This class is an implementation of a tree comparing method that counts the number of different pairs of the elements of the same clusters for two given flat trees. This class computes the similarity score between two trees obtained through K-Means clustering.

 */
public class FlatTreeComparer implements IClusterTreeComparer{
	public double Compare(Document xmlTree1, Document xmlTree2, double [][] dMatrix1, double [][] dMatrix2, String [] filesList1, String [] filesList2){
		ArrayList dmeList1 = getDistances(xmlTree1, dMatrix1);
		ArrayList dmeList2 = getDistances(xmlTree2, dMatrix2);
		int diff_count = 0;
		if(dmeList1.size() >= dmeList2.size()){
			for(int i=0;i<dmeList2.size();i++){
				DMElement dme2 = (DMElement)dmeList2.get(i);
				boolean diff = true;
				for(int j=0;j<dmeList1.size();j++){
					DMElement dme1 = (DMElement)dmeList1.get(j);
					if(filesList1[dme1.i].equals(filesList2[dme2.i])&&filesList1[dme1.j].equals(filesList2[dme2.j])){
						diff = false;					
					}
					if(filesList1[dme1.j].equals(filesList2[dme2.i])&&filesList1[dme1.i].equals(filesList2[dme2.j])){
						diff = false;					
					}
				}
				if(diff)diff_count++;
			}
			return 100 - 100*(double)(diff_count + (dmeList1.size() - dmeList2.size()))/(double)dmeList1.size();
		}else{
			for(int i=0;i<dmeList1.size();i++){
				DMElement dme1 = (DMElement)dmeList1.get(i);
				boolean diff = true;
				for(int j=0;j<dmeList2.size();j++){
					DMElement dme2 = (DMElement)dmeList2.get(j);
					if(filesList1[dme1.i].equals(filesList2[dme2.i])&&filesList1[dme1.j].equals(filesList2[dme2.j])){
						diff = false;					
					}
					if(filesList1[dme1.j].equals(filesList2[dme2.i])&&filesList1[dme1.i].equals(filesList2[dme2.j])){
						diff = false;					
					}
				}
				if(diff)diff_count++;
			}
			return 100 - 100*(double)(diff_count + (dmeList2.size() - dmeList1.size()))/(double)dmeList2.size();
		}
	}
	ArrayList getDistances(Document xmlTree, double [][] dMatrix){
		ArrayList dmeList = new ArrayList();
		Node root = xmlTree.getFirstChild();
		for(int i=0;i<root.getChildNodes().getLength();i++){
			Node branch = root.getChildNodes().item(i);
			int [] branchElemList = new int[branch.getChildNodes().getLength()];
			for(int j=0;j<branch.getChildNodes().getLength();j++){
				Node elem = branch.getChildNodes().item(j);
				for(int k=0;k<elem.getAttributes().getLength();k++){
					Node attrib = elem.getAttributes().item(k);
					if(attrib.getNodeName().toLowerCase()=="id"){
						branchElemList[j] = Integer.parseInt(attrib.getNodeValue());
						break;
					}
				}
			}
			addBranchDistances(branchElemList,dMatrix,dmeList);
		}
		return dmeList;
	}
	int sum(int n){
		int s = 0;
		for(int i=0;i<n;i++){
			s += i;
		}
		return s;
	}
	void addBranchDistances(int [] bel, double [][] dm, ArrayList dmeList){
		for(int i=0;i<bel.length;i++){
			for(int j=i+1;j<bel.length;j++){
				dmeList.add(new DMElement(bel[i],bel[j],dm[bel[i]][bel[j]]));
			}
		}
	}
}
